<?php


namespace App\Web\Model;

use App\Service\Crmapi as CrmService;
use App\Web\Facades\UserAuth;
use App\Web\Model\Customer as CustomerModel;
use EchoPHP\Facades\Db;
use EchoPHP\Facades\Log;
use EchoPHP\Facades\Redis;
use EchoPHP\Validator\Validator;
use Exception;


class Project extends Model {
    private $tableName = 'Project';
    private $flowKey = 'projectflowid:';

    private $contactFieldType = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];
    private $chargeWay = [1, 2, 3, 4, 5, 6, 7];
    private $chargeWayMax = 3;   //项目下交付方式种类个数上限
    private $chargeWayMaxCount = 50;   //一个交付方式下收费标准个数上限
    public $statusMap = [
        '01' => '进行中',
        '02' => '已暂停',
        '03' => '已结束',
    ];

    /**
     * Notes:新建项目
     * @param $params ['subid'] 客户id
     * @param $params ['crmnum'] crm项目编号
     * @param $params ['oprid'] 项目执行人数组
     * @param $params ['charger']  项目负责人id
     * @param $params ['tagcode'] 项目流程
     * @param $params ['contactfield'] 沟通表头数组
     * @return array
     */
    public function add($params) {

        if (empty($params['contactfield'])) {
            return [
                'status' => false,
                'message' => '操作失败',
                'validateFailure' => ['contactfield' => '未定义沟通表头']
            ];
        }
        if (empty($params['chargeway'])) {
            return [
                'status' => false,
                'message' => '操作失败',
                'validateFailure' => ['chargeway' => '未定义交付方式']
            ];
        }
        $customerModel = new Customer();

        //校验关联项目
        if (empty($params['crmnum'])) {
            return ['status' => false, 'message' => '操作失败', 'validateFailure' => ['crmnum' => '请选择关联项目']];
        }
        $sql = 'select projectid from ' . $this->tableName . ' where crmprojectnum = ? and status = ?';
        $crm = Db::selectOne($sql, [$params['crmnum'], '01']);
        if ($crm) {
            $sql = 'select cname,teamcode from ProjectOperator as po left join User as u on po.oprid = u.userid where po.projectid = ? and ischarger = ?';
            $charger = Db::selectOne($sql, [$crm['projectid'], 1]);
            $fullTeamName = (new Team())->fullName($charger['teamcode']);
            return [
                'status' => false,
                'message' => '操作失败',
                'validateFailure' => ['crmnum' => 'CRM项目编号：[' . $params['crmnum'] . '] 已被项目id：' . $crm['projectid'] . ' 使用，项目负责人：' . $fullTeamName . ' ' . $charger['cname']]
            ];
        }
        $sql = 'select * from CustomerSub where subid = ?';
        $subInfo = Db::selectOne($sql, [$params['subid']]);
        if (!$subInfo) {
            return ['status' => false, 'message' => '操作失败', 'validateFailure' => ['subid' => 'subid非法']];
        }
        //获取crm项目信息
        $crmService = new CrmService();
        $crmInfo = $crmService->getCrmProjectInfo($params['crmnum']);

        if (!$crmInfo || $crmInfo['accsubid'] != $subInfo['crmsubid']) {
            return ['status' => false, 'message' => '操作失败', 'validateFailure' => ['crmnum' => 'crm信息获取失败']];
        }
        //项目名称不可改
        $params['projectname'] = $crmInfo['probigname'];

        if (!$customerModel->chkSubFlow($params['tagcode'])) {
            return ['status' => false, 'message' => '操作失败', 'validateFailure' => ['tagcode' => '流程非法']];
        }
        $errorList = [];
        //写入交易公司项目表
        $user = UserAuth::getLoginInfo();

        Db::connect('jyrpo_pdo')->transaction(function () use ($params, $user, $crmInfo, $subInfo) {

            $sql = 'INSERT into ' . $this->tableName . ' (subid,projectname,crmprojectnum,crmstartdate,crmpreenddate,crmoperatorname,crmmanagername,crmprerevenue,crmdeliveryway,crmdeliverynum,crmfollowcontent,creator,updator,creatorname,updatorname,status,createdate,updatedate) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,Now(),Now())';
            $var = [
                $params['subid'],
                $params['projectname'],
                $params['crmnum'],
                $crmInfo['startdate'],
                $crmInfo['preenddate'],
                $crmInfo['operatorname'],
                $crmInfo['managerman'],
                $crmInfo['prefairamount'],
                $crmInfo['agreeway'],
                $crmInfo['agreeamount'],
                $crmInfo['rechargecontent'],
                $user['userid'],
                $user['userid'],
                $user['username'],
                $user['username'],
                '01',
            ];
            Db::connect('jyrpo_pdo')->insert($sql, $var);
            $projectId = Db::connect('jyrpo_pdo')->getLastInsertId();

            // 项目流程
            $sql = 'INSERT INTO ProjectFlow (subid,projectid,tagcodelist,status,creator,updator,createdate,updatedate) VALUES(?,?,?,?,?,?,Now(),Now())';
            $var = [$params['subid'], $projectId, $params['tagcode'], '01', $user['userid'], $user['userid']];
            Db::connect('jyrpo_pdo')->insert($sql, $var);

            // 添加项目负责人
            $sql = 'INSERT INTO ProjectOperator (subid,projectid,oprid,status,ischarger,creator,updator,createdate,updatedate)  VALUES (?,?,?,?,?,?,?,Now(),Now())';
            $var1 = [$params['subid'], $projectId, $params['charger'], '01', '1', $user['userid'], $user['userid']];
            if ($params['oprid']) {
                $params['oprid'] = array_diff($params['oprid'], [$params['charger']]);
                if ($params['oprid']) {
                    //项目执行人
                    $values = [];
                    foreach ($params['oprid'] as $item) {
                        $values[] = '(?,?,?,?,?,?,?,Now(),Now())';
                        $var2 = [$params['subid'], $projectId, $item, '01', '0', $user['userid'], $user['userid']];
                        $var1 = array_merge($var1, $var2);
                    }
                    $sql .= ',' . implode(',', $values);
                }
            }
            Db::connect('jyrpo_pdo')->insert($sql, $var1);

            //项目负责人加入职位执行人
            $sql = 'select distinct caseid from CaseOperator where projectid = ? and status = ?';
            $allCaseIds = array_column(Db::select($sql, [$projectId, '01']), 'caseid');
            if ($allCaseIds) {
                //将此用户之前职位执行人先删除再统一添加
                $inFlag = substr(str_repeat('?,', count($allCaseIds)), 0, -1);
                $sql = 'update CaseOperator set status = ? ,updatedate = NOW() where oprid = ? and status = ? and caseid in (' . $inFlag . ')';
                Db::connect('jyrpo_pdo')->update($sql, array_merge(['06', $params['charger'], '01'], $allCaseIds));

                $sql = 'insert into CaseOperator (subid,projectid,caseid,oprid,status,createdate,updatedate) values';
                $var = $values = [];
                foreach ($allCaseIds as $caseId) {
                    $values[] = '(?,?,?,?,?,NOW(),NOW())';
                    $var1 = [
                        $subInfo['subid'],
                        $projectId,
                        $caseId,
                        $params['charger'],
                        '01',
                    ];
                    $var = array_merge($var, $var1);
                }
                $sql .= implode(',', $values);
                Db::connect('jyrpo_pdo')->insert($sql, $var);
            }

            //写入沟通表头
            $sql = 'insert into ContactField (fieldname,showname,unit,type,arguments,creater,creatername,updater,
                    updatername,projectid,status,subid,issys,createdate,updatedate) values';
            $var = $values = [];
            $rule = [
                'fieldname|字段名称' => [
                    'required', 'maxLength' => 100
                ],
                'showname|字段显示名' => [
                    'required', 'maxLength' => 100
                ],
                'type|字段类型' => [
                    'required', 'number'
                ],
                'arguments' => [
                    'maxLength' => 4000
                ],
                'issys|是否系统默认表头' => [
                    'required', 'number'
                ],
            ];

            $validate = new Validator($rule);
            foreach ($params['contactfield'] as $key => $contactField) {
                if (!in_array($contactField['type'], $this->contactFieldType)) {
                    Log::error('添加沟通表头类型错误,projectid:' . $projectId . ' type:' . $contactField['type']);
                    $errorList[] = ['沟通表头NO.' . $key => '类型错误'];
                    continue;
                }
                $result = $validate->validate([
                    'fieldname' => $contactField['fieldname'],
                    'showname' => $contactField['showname'],
                    'type' => $contactField['type'],
                    'arguments' => json_encode($contactField['arguments']),
                    'issys' => $contactField['issys'],
                ]);
                if (!$result) {
                    Log::error('沟通表头NO.' . $key . '字段校验失败', $validate->getErrors());
                    $errorList[] = ['沟通表头NO.' . $key => $validate->getErrors()];
                    continue;
                }
                if (in_array($contactField['type'], [3, 4, 5, 6]) && empty($contactField['arguments'])) {
                    Log::error('新增沟通表头字段参数为空', $contactField);
                    $errorList[] = ['沟通表头NO.' . $key => '表头字段参数为空'];
                    continue;
                }
                $values[] = '(?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW())';
                $var1 = [
                    $contactField['fieldname'],
                    $contactField['showname'],
                    $contactField['unit'],
                    $contactField['type'],
                    json_encode($contactField['arguments']),
                    $user['userid'],
                    $user['cname'],
                    $user['userid'],
                    $user['cname'],
                    $projectId,
                    '01',
                    $params['subid'],
                    $contactField['issys']
                ];
                $var = array_merge($var, $var1);
            }
            //避免字段校验全出错的情况
            if (!empty($values)) {
                $sql .= implode(',', $values);
                $result = Db::connect('jyrpo_pdo')->insert($sql, $var);
                if (!$result) {
                    Log::error('projectid: ' . $projectId . '添加沟通表头失败,表头信息: ' . $params['contactfield']);
                }
            } else {
                Log::error('projectid: ' . $projectId . '添加沟通表头失败,表头信息: ' . $params['contactfield']);
            }


            //添加交付方式
            $rule1 = [
                'chargeway|交付方式' => [
                    'required', 'number'
                ],
                'targetnum|交付目标' => [
                    'required', 'number', 'min' => 0, 'max' => 2147483647
                ],
                'bindflow|绑定节点' => [
                    'required', 'maxLength' => 200
                ],
                'children|收费方式' => [
                    'required'
                ],
            ];
            $rule2 = [
                'chargetype|收费方式' => [
                    'required', 'number'
                ],
                'standard|收费标准' => [
                    'required', 'number', 'maxLength' => 100
                ],
                'salarytype|薪资类型' => [
                    'required',
                ],
                'salaryfrom|薪资起始值' => [
                    'number', 'min' => 0, 'max' => 200000000
                ],
                'salaryto|薪资结束值' => [
                    'number', 'min' => 0, 'max' => 200000000
                ],
            ];
            $validate1 = new Validator($rule1);
            $validate2 = new Validator($rule2);
            foreach ($params['chargeway'] as $key => $chargeway) {
                $result = $validate1->validate([
                    'chargeway' => $chargeway['chargeway'],
                    'targetnum' => $chargeway['targetnum'],
                    'bindflow' => $chargeway['bindflow'],
                    'children' => $chargeway['children']
                ]);
                if (!$result) {
                    Log::error('交付方式NO.' . $key . '字段校验失败', $validate1->getErrors());
                    $errorList[] = ['交付方式NO.' . $key => $validate->getErrors()];
                    continue;
                }
                if (!in_array($chargeway['chargeway'], $this->chargeWay)) {
                    Log::error('交付方式NO.' . $key . '类型错误');
                    $errorList[] = ['交付方式NO.' . $key => '类型错误'];
                    continue;
                }
                $insertSql = 'insert into ChargeWay (projectid,subid,chargeway,targetnum,bindflow,status,
                creater,creatername,updater,updatername,createdate,updatedate) values (?,?,?,?,?,?,?,?,?,?,NOW(),NOW())';
                $insertVar = [
                    $projectId,
                    $params['subid'],
                    $chargeway['chargeway'],
                    $chargeway['targetnum'],
                    $chargeway['bindflow'],
                    '01',
                    $user['userid'],
                    $user['cname'],
                    $user['userid'],
                    $user['cname'],
                ];
                $result = Db::connect('jyrpo_pdo')->insert($insertSql, $insertVar);
                if (!$result) {
                    Log::error('新增交付方式失败', $chargeway);
                    $errorList[] = ['交付方式NO.' . $key => '添加失败'];
                    continue;
                }
                $chargeId = Db::connect('jyrpo_pdo')->getLastInsertId();
                $insertSql2 = 'insert into ChargeStandard (projectid,subid,chargeid,chargetype,standard,salarytype,salaryfrom,salaryto,status,
                creater,creatername,updater,updatername,createdate,updatedate) values ';
                $insertVar2 = $values = [];
                foreach ($chargeway['children'] as $key1 => $chargeStandard) {
                    $result = $validate2->validate([
                        'chargetype' => $chargeStandard['chargetype'],
                        'standard' => $chargeStandard['standard'],
                        'salarytype' => $chargeStandard['salarytype'],
                        'salaryfrom' => $chargeStandard['salaryfrom'],
                        'salaryto' => $chargeStandard['salaryto']
                    ]);
                    if (!$result) {
                        Log::error('收费方式NO.' . $key1 . '字段校验失败', $validate1->getErrors());
                        $errorList[] = ['收费方式NO.' . $key1 => $validate->getErrors()];
                        continue;
                    }
                    $values[] = '(?,?,?,?,?,?,?,?,?,?,?,?,?,Now(),Now())';
                    $var2 = [
                        $projectId,
                        $params['subid'],
                        $chargeId,
                        $chargeStandard['chargetype'],
                        $chargeStandard['standard'],
                        $chargeStandard['salarytype'],
                        $chargeStandard['salaryfrom'],
                        $chargeStandard['salaryto'],
                        '01',
                        $user['userid'],
                        $user['cname'],
                        $user['userid'],
                        $user['cname'],
                    ];
                    $insertVar2 = array_merge($insertVar2, $var2);
                }
                //避免字段校验全部出错的情况
                if (!empty($values)) {
                    $insertSql2 .= implode(',', $values);
                    $result = Db::connect('jyrpo_pdo')->insert($insertSql2, $insertVar2);
                    if (!$result) {
                        Log::error('新增收费标准失败', $chargeStandard);
                    }
                } else {
                    Log::error('新增收费标准失败', $chargeStandard);
                }
            }
        });
        return [
            'status' => true,
            'message' => '更新成功',
            'errorlist' => $errorList,
        ];
    }

    public function detail($projectId) {
        $result = $this->chkGetRight($projectId);
        if (!$result) {
            return [];
        }
        $sql = 'select projectid,p.subid,s.subname,projectname,p.status,crmprojectnum,crmoperatorname,crmmanagername,crmprerevenue,crmdeliveryway,crmdeliverynum,crmfollowcontent from ' . $this->tableName . ' as p left join CustomerSub as s on p.subid = s.subid where p.projectid = ?';
        $result = Db::selectOne($sql, [$projectId]);
        $editRight = $this->chkEditRight($projectId);
        $customerModel = new CustomerModel();
        $subId = $result['subid'] ?? 0;
        $subEditRight = $customerModel->chkEditSubRight($subId);
        $result['ischarger'] = $editRight ? 1 : 0;
        $result['issubcharger'] = $subEditRight ? 1 : 0;
        return $result;
    }

    /**
     * Notes:修改项目crm关联信息
     * @param $params ['crmnum'] crm大项目编号
     * @param $params ['projectid'] 项目id
     * @return array
     */
    public function editCrmInfo($params) {
        //校验关联项目
        if (empty($params['crmnum'])) {
            return ['status' => false, 'message' => '操作失败', 'validateFailure' => ['crmnum' => '请选择关联项目']];
        }

        if (!$this->chkEditRight($params['projectid'])) {
            return ['status' => false, 'message' => '无修改权限'];
        }
        $sql = 'select projectid from ' . $this->tableName . ' where crmprojectnum = ?';
        $existCrmProject = Db::selectOne($sql, [$params['crmnum']]);
        if ($existCrmProject) {
            return [
                'status' => false,
                'message' => '操作失败',
                'validateFailure' => ['crmnum' => 'CRM项目编号：[' . $params['crmnum'] . '] 已被项目id：' . $existCrmProject['projectid'] . ' 使用']
            ];
        }
        $sql = 'select crmsubid from Project as p left join CustomerSub as s on p.subid = s.subid where p.projectid = ?';
        $crmSubId = Db::selectOne($sql, [$params['projectid']]);
        if (!$crmSubId) {
            return ['status' => false, 'message' => '操作失败', 'validateFailure' => ['projectid' => '项目id非法']];
        }
        //获取crm项目信息
        $crmService = new CrmService();
        $crmInfo = $crmService->getCrmProjectInfo($params['crmnum']);
        if (!$crmInfo || $crmSubId['crmsubid'] != $crmInfo['accsubid']) {
            return [
                'status' => false,
                'message' => '操作失败',
                'validateFailure' => ['crmnum' => 'crm信息获取失败']
            ];
        }
        $user = UserAuth::getLoginInfo();
        $sql = 'update ' . $this->tableName . ' set crmprojectnum = ?,crmstartdate = ?,crmpreenddate = ? ,crmoperatorname = ?,crmmanagername = ?,crmprerevenue = ?,crmdeliveryway = ?,crmdeliverynum = ?,crmfollowcontent = ?,updator = ?,updatorname = ?,updatedate=Now() WHERE  projectid=?';
        $var = [
            $params['crmnum'],
            $crmInfo['startdate'],
            $crmInfo['preenddate'],
            $crmInfo['operatorname'],
            $crmInfo['managerman'],
            $crmInfo['prefairamount'],
            $crmInfo['agreeway'],
            $crmInfo['agreeamount'],
            $crmInfo['rechargecontent'],
            $user['userid'],
            $user['username'],
            $params['projectid'],
        ];
        $result = Db::update($sql, $var);
        return [
            'status' => $result == 1,
            'message' => $result == 1 ? '更新成功' : '更新失败',
        ];
    }

    /**
     * Notes:同步项目crm信息
     * @param $projectId
     * @param array $user
     * @return array
     */
    public function crmInfoSync($projectId, $user = []) {
        $sql = 'select s.subid,s.crmsubid,p.crmprojectnum from ' . $this->tableName . ' as p left join CustomerSub as s on p.subid = s.subid where projectid = ?';
        $projectInfo = Db::selectOne($sql, [$projectId]);
        if (!$projectInfo) {
            return ['status' => false, 'message' => '操作失败'];
        }
        //获取crm项目信息
        $crmService = new CrmService();
        $crmInfo = $crmService->getCrmProjectInfo($projectInfo['crmprojectnum']);
        if (!$crmInfo || $crmInfo['accsubid'] != $projectInfo['crmsubid']) {
            return ['status' => false, 'message' => 'crm信息获取失败',];
        }
        $sql = 'update ' . $this->tableName . ' set projectname = ?, crmstartdate = ? ,crmpreenddate = ? ,crmoperatorname = ? ,crmmanagername = ? ,crmprerevenue = ? ,crmdeliveryway = ? ,crmdeliverynum = ?,crmfollowcontent = ? , updator = ? , updatorname = ? , updatedate = NOW() where projectid = ?';
        $var = [
            $crmInfo['probigname'],
            $crmInfo['startdate'],
            $crmInfo['preenddate'],
            $crmInfo['operatorname'],
            $crmInfo['managerman'],
            $crmInfo['prefairamount'],
            $crmInfo['agreeway'],
            $crmInfo['agreeamount'],
            $crmInfo['rechargecontent'],
            $user['userid'] ?? 0,
            $user['username'] ?? 0,
            $projectId
        ];
        $result = Db::connect('jyrpo_pdo')->update($sql, $var);
        return [
            'status' => $result == 1,
            'message' => $result == 1 ? '更新成功' : '操作失败',
            'crmprojectinfo' => $crmInfo
        ];
    }

    public function getAllCrmProjectBySubId($subId) {
        $sql = 'select crmsubid from CustomerSub where subid = ?';
        $crmSubId = Db::selectOne($sql, [$subId]);
        if (!$crmSubId) {
            return ['status' => false, 'message' => '操作失败', 'validateFailure' => ['subid' => '客户id非法']];
        }
        $crmSubId = $crmSubId['crmsubid'];
        $sql = 'select projectid,crmprojectnum from Project where subid = ?';
        $allProject = Db::select($sql, [$subId]);
        foreach ($allProject as $project) {
            $projectMap[$project['crmprojectnum']] = $project['projectid'];
        }
        $crmService = new CrmService();
        $result = $crmService->getCrmProjectList($crmSubId);
        foreach ($result as &$item) {
            $item['projectid'] = $projectMap[$item['probignumber']] ?? '';
        }
        return $result;
    }

    /**
     * Notes:修改项目状态
     * @param $projectId
     * @param $status
     * @return array
     */
    public function editStatus($projectId, $status) {
        if (!$this->chkEditRight($projectId)) {
            return ['status' => false, 'message' => '无修改权限'];
        }
        if ($projectId <= 0) {
            return [
                'status' => false,
                'message' => '项目ID不能为空'
            ];
        }
        if (!in_array($status, ['01', '02', '03'])) {
            return [
                'status' => false,
                'message' => '项目状态错误'
            ];
        }
        $statement1 = $statement2 = [];
        switch ($status) {
            //暂停项目重新开始
            case '01':
                $updateSql = 'update Project set status = ? where projectid = ? and status != ?';
                $var = ['01', $projectId, '03'];
                $statement1 = Db::connect()->prepareStatement($updateSql, $var);
                $updateSql = 'update SCase set status = ? where projectid = ? and status = ?';
                $var = ['01', $projectId, '04'];
                $statement2 = Db::connect()->prepareStatement($updateSql, $var);
                $result = Db::connect()->prepareTransactionStatement(false, $statement1, $statement2)->execute();
                break;
            //暂停项目
            case '02':
                $updateSql = 'update Project set status = ? where projectid = ? and status != ?';
                $var = ['02', $projectId, '03'];
                $statement1 = Db::connect()->prepareStatement($updateSql, $var);
                $updateSql = 'update SCase set status = ? where projectid = ? and status = ?';
                $var = ['04', $projectId, '01'];
                $statement2 = Db::connect()->prepareStatement($updateSql, $var);
                $result = Db::connect()->prepareTransactionStatement(false, $statement1, $statement2)->execute();
                break;
            case '03':
                //查看项目下是否有未结束的职位
                $sql = 'select caseid from SCase where projectid = ? and status != ?';
                $var = [$projectId, '03'];
                $result = Db::select($sql, $var);
                if (!empty($result)) {
                    return [
                        'status' => false,
                        'message' => '存在未结束的职位，无法结束项目'
                    ];
                }
                //不存在未结束的项目，结束该项目
                $updateSql = 'update Project set status = ? where projectid = ?';
                $updateVar = ['03', $projectId];
                $result = Db::update($updateSql, $updateVar);
                break;
        }
        if (!$result) {
            Log::error('项目状态修改失败,projectid:' . $projectId);
            return ['status' => false, 'message' => '操作失败'];
        }

        return [
            'status' => true,
            'message' => '操作成功'
        ];
    }

    /**
     * Notes:修改项目流程
     * @param $params ['projectid']项目id
     * @param $params ['tagcode']流程列
     * @return array
     */
    public function editFlow($params) {
        $user = UserAuth::getLoginInfo();
        if (!$this->chkEditRight($params['projectid'])) {
            return ['status' => false, 'message' => '无修改权限'];
        }
        $customerModel = new Customer();
        if (!$customerModel->chkSubFlow($params['tagcode'])) {
            return ['status' => false, 'message' => '操作失败', 'validateFailure' => ['tagcode' => '流程非法']];
        }
        $caseFlowModel = new CaseFlow();
        $tagCode = $caseFlowModel->getProjectFlowCode($params['projectid']);
        $flowList = explode(',', $tagCode);
        //差异节点
        $delFlowAts = array_diff($flowList, explode(',', $params['tagcode']));
        if ($delFlowAts) {
            foreach ($delFlowAts as $delFlowAt) {
                //节点下是否绑定交付方式
                $flowInfo = $caseFlowModel->getFlowInfo($delFlowAt);
                $flowChildCodes = array_keys($flowInfo['child']);
                $flowChildFullCodes = array_map(function ($childCode) use ($delFlowAt) {
                    return $delFlowAt . $childCode;
                }, $flowChildCodes);
                $sql = 'select bindflow from ChargeWay where projectid = ?  and status = ?';
                $existBindFlow = Db::selectOne($sql, [$params['projectid'], '01']);
                if ($existBindFlow) {
                    $existBindFlow = explode(',', $existBindFlow['bindflow']);
                    if (array_diff($existBindFlow, $flowChildFullCodes) != $existBindFlow) {
                        return ['status' => false, 'message' => '项目流程节点已绑定支付方式，无法删除'];
                    }
                }
                //节点下是否有职位
                $caseModel = new CaseModel();
                $existCase = $caseModel->getFlowCountInProject($params['projectid'], $delFlowAt);
                if ($existCase) {
                    return ['status' => false, 'message' => '项目流程节点下有职位，无法删除'];
                }
            }
        }

        $sql = 'update ProjectFlow set tagcodelist = ? , updator = ? , updatedate = NOW() where projectid = ? and status = ?';
        $result = Db::update($sql, [$params['tagcode'], $user['userid'], $params['projectid'], '01']);
        if ($result) {
            $redisClient = Redis::connect('projectflow');
            $flowKey = $this->flowKey . $params['projectid'];
            $redisClient->del($flowKey);
        }
        return [
            'status' => $result == 1,
            'message' => $result == 1 ? '更新成功' : '操作失败',
        ];
    }

    /**
     * 添加项目沟通表头
     * @param $projectId    项目id
     * @param $contactField 沟通表头
     * @return array
     */
    public function addContactField($projectId, array $contactField) {
        if (empty($projectId)) {
            return [
                'status' => false,
                'message' => '项目不能为空'
            ];
        }
        $rule = [
            'fieldname|字段名称' => [
                'required', 'maxLength' => 100
            ],
            'showname|字段显示名' => [
                'required', 'maxLength' => 100
            ],
            'type|字段类型' => [
                'required', 'number'
            ],
            'arguments' => [
                'maxLength' => 4000
            ],
            'issys|是否系统默认表头' => [
                'required', 'number'
            ],
        ];

        $validate = new Validator($rule);
        $result = $validate->validate([
            'fieldname' => $contactField['fieldname'],
            'showname' => $contactField['showname'],
            'type' => $contactField['type'],
            'arguments' => json_encode($contactField['arguments']),
            'issys' => $contactField['issys'],

        ]);
        if (!$result) {
            return ['status' => false, 'message' => '添加失败', 'errorFields' => $validate->getErrors()];
        }
        if (in_array($contactField['type'], [3, 4, 5, 6]) && empty($contactField['arguments'])) {
            return ['status' => false, 'message' => '添加失败', 'errorFields' => '字段参数不能为空'];
        }

        //操作人权限校验，只有项目负责人能够修改
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }
        $sql = 'select subid from Project where projectid = ?';
        $var = [$projectId];
        $subId = Db::selectOne($sql, $var);
        if (empty($subId)) {
            return [
                'status' => false,
                'message' => '项目不存在'
            ];
        }
        $oprInfo = UserAuth::getLoginInfo();
        $insertSql = 'insert into ContactField (fieldname,showname,unit,type,arguments,creater,creatername,updater,
                    updatername,projectid,status,subid,issys,createdate,updatedate) values (?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW())';
        $insertVar = [
            $contactField['fieldname'],
            $contactField['showname'],
            $contactField['unit'],
            $contactField['type'],
            json_encode($contactField['arguments']),
            $oprInfo['userid'],
            $oprInfo['cname'],
            $oprInfo['userid'],
            $oprInfo['cname'],
            $projectId,
            '01',
            $subId['subid'],
            $contactField['issys']
        ];
        $result = Db::insert($insertSql, $insertVar);
        if (!$result) {
            Log::error('项目id:' . $projectId . '新增沟通表头失败');
            return [
                'status' => false,
                'message' => '新增失败'
            ];
        }
        return [
            'status' => true,
            'message' => '新增成功'
        ];
    }

    /**
     * 修改项目沟通表头
     * @param $projectId    项目id
     * @param $contactField 沟通表头
     * @return array
     */
    public function editContactField($contactFieldId, array $contactField) {
        if (empty($contactFieldId)) {
            return [
                'status' => false,
                'message' => '请选择沟通表头'
            ];
        }
        $rule = [
            'fieldname|字段名称' => [
                'required', 'maxLength' => 100
            ],
            'showname|字段显示名' => [
                'required', 'maxLength' => 100
            ],
            'type|字段类型' => [
                'required', 'number'
            ],
            'issys|是否系统默认表头' => [
                'required', 'number'
            ],
        ];

        $validate = new Validator($rule);
        $result = $validate->validate([
            'fieldname' => $contactField['fieldname'],
            'showname' => $contactField['showname'],
            'type' => $contactField['type'],
            'issys' => $contactField['issys'],

        ]);
        if (!$result) {
            return ['status' => false, 'message' => '添加失败', 'errorFields' => $validate->getErrors()];
        }
        if (in_array($contactField['type'], [3, 4, 5, 6]) && empty($contactField['arguments'])) {
            return ['status' => false, 'message' => '添加失败', 'errorFields' => '字段参数不能为空'];
        }
        $sql = 'select projectid from ContactField where id = ? and status = ?';
        $var = [$contactFieldId, '01'];
        $projectId = Db::selectOne($sql, $var)['projectid'];
        if (empty($projectId)) {
            return [
                'status' => false,
                'message' => '表头不存在'
            ];
        }
        //操作人权限校验，只有项目负责人能够修改
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }

//        //检查表头是否已被使用
//        $sql = 'select fieldidlist from CaseContactField where caseid in (select caseid from SCase where projectid = ?) and status = ?';
//        $var = [$projectId, '01'];
//        $result = Db::select($sql, $var);
//        $usedFiledIds = '';
//        foreach ($result as $fieldList) {
//            $usedFiledIds .= $fieldList['fieldidlist'] . ',';
//        }
//        $usedFiledIds = explode(',', substr($usedFiledIds, 0, -1));
//        if (in_array($contactFieldId, $usedFiledIds)) {
//            return [
//                'status' => false,
//                'message' => '该表头已被使用，不能修改'
//            ];
//        }

        $oprInfo = UserAuth::getLoginInfo();
        $updateSql = 'update ContactField set fieldname = ?, showname = ?, unit = ?, type = ?, arguments = ?, updater = ?,
                    updatername = ?, issys = ? ,updatedate = Now() where id = ?';
        $updateVar = [
            $contactField['fieldname'],
            $contactField['showname'],
            $contactField['unit'],
            $contactField['type'],
            json_encode($contactField['arguments']),
            $oprInfo['userid'],
            $oprInfo['cname'],
            $contactField['issys'],
            $contactFieldId
        ];
        $result = Db::update($updateSql, $updateVar);
        if (!$result) {
            Log::error('表头id:' . $contactFieldId . '修改沟通表头失败');
            return [
                'status' => false,
                'message' => '无数据更新'
            ];
        }
        return [
            'status' => true,
            'message' => '更新成功'
        ];
    }

    /**
     * 删除项目 沟通表头
     * @param $projectId    项目id
     * @param $contactField 沟通表头
     * @return array
     */
    public function deleteContactField($contactFieldId) {
        if (empty($contactFieldId)) {
            return [
                'status' => false,
                'message' => '请选择要删除的内容'
            ];
        }
        $sql = 'select projectid from ContactField where id = ? and status = ?';
        $var = [$contactFieldId, '01'];
        $projectId = Db::selectOne($sql, $var)['projectid'];
        if (empty($projectId)) {
            return [
                'status' => false,
                'message' => '您删除的内容不存在'
            ];
        }
        //操作人权限校验，只有项目负责人能够修改
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }

        $sql = 'select fieldidlist from CaseContactField where caseid in (select caseid from SCase where projectid = ?) and status = ?';
        $var = [$projectId, '01'];
        $result = Db::select($sql, $var);
        $usedFiledIds = '';
        foreach ($result as $fieldList) {
            $usedFiledIds .= $fieldList['fieldidlist'] . ',';
        }
        $usedFiledIds = explode(',', substr($usedFiledIds, 0, -1));
        if (in_array($contactFieldId, $usedFiledIds)) {
            return [
                'status' => false,
                'message' => '该表头已被使用，不能删除'
            ];
        }
        $sql = 'select count(1) as num from ContactField where projectid = ? and status = ?';
        $var = [$projectId, '01'];
        $remainCount = Db::select($sql, $var)[0]['num'];
        if ($remainCount <= 1) {
            return [
                'status' => false,
                'message' => '至少应该存在一个沟通表头方式'
            ];
        }
        $oprInfo = UserAuth::getLoginInfo();
        $deleteSql = 'update ContactField set status = ? , updater = ? , updatername = ? , updatedate = Now() where id = ?';
        $deleteVar = ['06', $oprInfo['userid'], $oprInfo['cname'], $contactFieldId];
        $result = Db::update($deleteSql, $deleteVar);
        if (!$result) {
            Log::error('沟通表头 id:' . $contactFieldId . '删除失败');
            return [
                'status' => false,
                'message' => '删除失败'
            ];
        }
        return [
            'status' => true,
            'message' => '删除成功'
        ];
    }

    /**
     * 删除交付方式
     * @param $chargeId
     * @return array
     */
    public function deleteChargeWay($chargeId) {
        if (empty($chargeId)) {
            return [
                'status' => false,
                'message' => '请选择要删除的内容'
            ];
        }
        $sql = 'select projectid from ChargeWay where id = ? and status = ?';
        $var = [$chargeId, '01'];
        $projectId = Db::selectOne($sql, $var)['projectid'];
        if (empty($projectId)) {
            return [
                'status' => false,
                'message' => '您删除的内容不存在'
            ];
        }
        //操作人权限校验，只有项目负责人能够修改
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }
        $sql = 'select id from CaseChargeWay where chargewayid = ? and status = ?';
        $var = [$chargeId, '01'];
        $result = Db::select($sql, $var);
        if (!empty($result)) {
            return [
                'status' => false,
                'message' => '该支付方式已被使用，无法删除'
            ];
        }
        $sql = 'select count(1) as num from ChargeWay where projectid = ? and status = ?';
        $var = [$projectId, '01'];
        $remainCount = Db::select($sql, $var)[0]['num'];
        if ($remainCount <= 1) {
            return [
                'status' => false,
                'message' => '至少应该存在一个交付方式'
            ];
        }
        $oprInfo = UserAuth::getLoginInfo();
        $deleteSql = 'update ChargeWay set status = ? , updater = ? , updatername = ? , updatedate = Now() where id = ?';
        $deleteVar = ['06', $oprInfo['userid'], $oprInfo['cname'], $chargeId];
        $statement1 = Db::connect()->prepareStatement($deleteSql, $deleteVar);
        $deleteSql = 'update ChargeStandard set status = ? , updater = ? , updatername = ? , updatedate = Now() where chargeid = ?';
        $deleteVar = ['06', $oprInfo['userid'], $oprInfo['cname'], $chargeId];
        $statement2 = Db::connect()->prepareStatement($deleteSql, $deleteVar);
        $result = Db::connect()->prepareTransactionStatement(false, $statement1, $statement2)->execute();
        if (!$result) {
            Log::error('交付方式 id:' . $chargeId . '删除失败');
            return [
                'status' => false,
                'message' => '删除失败'
            ];
        }
        return [
            'status' => true,
            'message' => '删除成功'
        ];
    }

    /**
     * 删除交付方式下收费标准
     * @param $chargeId
     * @return array
     */
    public function deleteChargeStandard($chargeId) {
        if (empty($chargeId)) {
            return [
                'status' => false,
                'message' => '请选择要删除的内容'
            ];
        }
        $sql = 'select projectid from ChargeStandard where id = ? and status = ?';
        $var = [$chargeId, '01'];
        $projectId = Db::selectOne($sql, $var)['projectid'];
        if (empty($projectId)) {
            return [
                'status' => false,
                'message' => '您删除的内容不存在'
            ];
        }
        //操作人权限校验，只有项目负责人能够修改
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }
        $sql = 'select id from CaseChargeWay where chargestandardid = ? and status = ?';
        $var = [$chargeId, '01'];
        $result = Db::select($sql, $var);
        if (!empty($result)) {
            return [
                'status' => false,
                'message' => '该收费方式已被使用，无法删除'
            ];
        }
        $sql = 'select count(1) as num from ChargeStandard where projectid = ? and status = ?';
        $var = [$projectId, '01'];
        $remainCount = Db::select($sql, $var)[0]['num'];
        if ($remainCount <= 1) {
            return [
                'status' => false,
                'message' => '至少应该存在一个收费方式'
            ];
        }
        $oprInfo = UserAuth::getLoginInfo();
        $deleteSql = 'update ChargeStandard set status = ? , updater = ? , updatername = ? , updatedate = Now() where id = ?';
        $deleteVar = ['06', $oprInfo['userid'], $oprInfo['cname'], $chargeId];
        $result = Db::update($deleteSql, $deleteVar);
        if (!$result) {
            Log::error('交付方式 id:' . $chargeId . '删除失败');
            return [
                'status' => false,
                'message' => '删除失败'
            ];
        }
        return [
            'status' => true,
            'message' => '删除成功'
        ];
    }

    /**
     * 项目添加交付方式
     * @param $projectId
     * @param $chargeway
     * @return array
     */
    public function addChargeWay($projectId, $chargeway) {
        if (empty($projectId)) {
            return [
                'status' => false,
                'message' => '项目不能为空'
            ];
        }
        $rule1 = [
            'chargeway|交付方式' => [
                'required', 'number'
            ],
            'targetnum|交付目标' => [
                'required', 'number'
            ],
            'bindflow|绑定节点' => [
                'required', 'maxLength' => 200
            ],
            'children|收费方式' => [
                'required'
            ],
        ];
        $rule2 = [
            'chargetype|收费方式' => [
                'required', 'number'
            ],
            'standard|收费标准' => [
                'required', 'maxLength' => 100
            ],
            'salarytype|薪资类型' => [
                'required',
            ],
            'salaryfrom|薪资起始值' => [
                'number', 'min' => 0, 'max' => 200000000
            ],
            'salaryto|薪资结束值' => [
                'number', 'min' => 0, 'max' => 200000000
            ],
        ];

        $validate1 = new Validator($rule1);
        $validate2 = new Validator($rule2);
        $result = $validate1->validate([
            'chargeway' => $chargeway['chargeway'],
            'targetnum' => $chargeway['targetnum'],
            'bindflow' => $chargeway['bindflow'],
            'children' => $chargeway['children'],

        ]);
        if (!$result) {
            return ['status' => false, 'message' => '添加失败', 'errorFields' => $validate1->getErrors()];
        }

        //操作人权限校验，只有项目负责人能够修改
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }
        $sql = 'select subid from Project where projectid = ?';
        $var = [$projectId];
        $subId = Db::selectOne($sql, $var);
        if (empty($subId)) {
            return [
                'status' => false,
                'message' => '项目不存在'
            ];
        }
        $sql = 'select count(id) as num from ChargeWay where projectid = ? and status = ?';
        $var = [$projectId, '01'];
        $result = Db::select($sql, $var)[0]['num'];
        if ($result >= $this->chargeWayMax) {
            return [
                'status' => false,
                'message' => '超过项目交付方式上限'
            ];
        }
        if (!in_array($chargeway['chargeway'], $this->chargeWay)) {
            return [
                'status' => false,
                'message' => '添加交付方式类型错误'
            ];
        }

        foreach ($chargeway['children'] as $key => $item) {
            if (count($item) > $this->chargeWayMaxCount) {
                return [
                    'status' => false,
                    'message' => '第' . $key . '项超过交付方式收费标准数量上限'
                ];
            }
        }
        $oprInfo = UserAuth::getLoginInfo();
        $insertSql = 'insert into ChargeWay (projectid,subid,chargeway,targetnum,bindflow,status,
                creater,creatername,updater,updatername,createdate,updatedate) values (?,?,?,?,?,?,?,?,?,?,NOW(),NOW())';
        $insertVar = [
            $projectId,
            $subId['subid'],
            $chargeway['chargeway'],
            $chargeway['targetnum'],
            $chargeway['bindflow'],
            '01',
            $oprInfo['userid'],
            $oprInfo['cname'],
            $oprInfo['userid'],
            $oprInfo['cname'],
        ];
        $result = Db::insert($insertSql, $insertVar);
        if (!$result) {
            return [
                'status' => false,
                'message' => '新增失败'
            ];
        }
        $chargeId = Db::getLastInsertId();

        $insertSql2 = 'insert into ChargeStandard (projectid,subid,chargeid,chargetype,standard,salarytype,salaryfrom,salaryto,status,
               creater,creatername,updater,updatername,createdate,updatedate) values ';
        $insertVar2 = $values = [];
        foreach ($chargeway['children'] as $chargeStandard) {
            $result = $validate2->validate([
                'chargetype' => $chargeStandard['chargetype'],
                'standard' => $chargeStandard['standard'],
                'salarytype' => $chargeStandard['salarytype'],
                'salaryfrom' => $chargeStandard['salaryfrom'],
                'salaryto' => $chargeStandard['salaryto']
            ]);
            if (!$result) {
                return ['status' => false, 'message' => '添加失败', 'errorFields' => $validate2->getErrors()];
            }
            $values[] = '(?,?,?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW())';
            $var2 = [
                $projectId,
                $subId,
                $chargeId,
                $chargeStandard['chargetype'],
                $chargeStandard['standard'],
                $chargeStandard['salarytype'],
                $chargeStandard['salaryfrom'],
                $chargeStandard['salaryto'],
                '01',
                $oprInfo['userid'],
                $oprInfo['cname'],
                $oprInfo['userid'],
                $oprInfo['cname'],
            ];
            $insertVar2 = array_merge($insertVar2, $var2);
        }
        $insertSql2 .= implode(',', $values);
        $result = Db::insert($insertSql2, $insertVar2);
        if (!$result) {
            Log::error('新增收费标准失败', $chargeStandard);
        }

        return [
            'status' => true,
            'message' => '新增成功'
        ];
    }

    public function addChargeStandard($chargeId, $standard) {
        if (empty($chargeId)) {
            return [
                'status' => false,
                'message' => '交付方式id不能为空'
            ];
        }
        if (empty($standard)) {
            return [
                'status' => false,
                'message' => '收费标准不能为空'
            ];
        }
        $rule = [
            'chargetype|收费方式' => [
                'required', 'number'
            ],
            'standard|收费标准' => [
                'required', 'number', 'maxLength' => 100
            ],
            'salarytype|薪资类型' => [
                'required',
            ],
            'salaryfrom|薪资起始值' => [
                'number', 'min' => 0, 'max' => 200000000
            ],
            'salaryto|薪资结束值' => [
                'number', 'min' => 0, 'max' => 200000000
            ],
        ];

        $validate = new Validator($rule);
        $result = $validate->validate([
            'chargetype' => $standard['chargetype'],
            'standard' => $standard['standard'],
            'salarytype' => $standard['salarytype'],
            'salaryfrom' => $standard['salaryfrom'],
            'salaryto' => $standard['salaryto']
        ]);
        if (!$result) {
            return ['status' => false, 'message' => '添加失败', 'errorFields' => $validate->getErrors()];
        }
        $sql = 'select subid,projectid from ChargeWay where id = ? and status = ?';
        $var = [$chargeId, '01'];
        $result = Db::selectOne($sql, $var);
        if (empty($result)) {
            return [
                'status' => false,
                'message' => '该支付方式不存在'
            ];
        }
        $projectId = $result['projectid'];
        $subId = $result['subid'];
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }
        $sql = 'select count(1) as num from ChargeStandard where chargeid = ? and status = ?';
        $var = [$chargeId, '01'];
        $count = Db::select($sql, $var)[0]['num'];
        if ($count >= $this->chargeWayMaxCount) {
            return [
                'status' => false,
                'message' => '超过收费标准个数上限'
            ];
        }
        $oprInfo = UserAuth::getLoginInfo();
        $insertSql = 'insert into ChargeStandard (projectid,subid,chargeid,chargetype,standard,salarytype,salaryfrom,salaryto,status,
                    creater,creatername,updater,updatername,createdate,updatedate) values (?,?,?,?,?,?,?,?,?,?,?,?,?,Now(),Now())';
        $insertVar = [
            $projectId,
            $subId,
            $chargeId,
            $standard['chargetype'],
            $standard['standard'],
            $standard['salarytype'],
            $standard['salaryfrom'],
            $standard['salaryto'],
            '01',
            $oprInfo['userid'],
            $oprInfo['cname'],
            $oprInfo['userid'],
            $oprInfo['cname']
        ];
        $result = Db::insert($insertSql, $insertVar);
        return [
            'status' => $result ? true : false,
            'message' => $result ? '添加成功' : '添加失败',
            'id' => Db::getLastInsertId()
        ];
    }

    /**
     * 修改项目交付方式
     * @param $chargewayId  交付方式id
     * @param $chargeway    交付方式 数组
     * @return array
     */
    public function editChargeWay($chargeId, $params) {
        if (empty($chargeId)) {
            return [
                'status' => false,
                'message' => '交付方式id不能为空'
            ];
        }
        $rule = [
            'chargeway|交付方式' => [
                'required', 'number'
            ],
            'targetnum|交付目标' => [
                'required', 'number', 'min' => 0, 'max' => 2147483647
            ],
            'bindflow|绑定节点' => [
                'required', 'maxLength' => 200
            ],
        ];

        $validate = new Validator($rule);

        $result = $validate->validate([
            'chargeway' => $params['chargeway'],
            'targetnum' => $params['targetnum'],
            'bindflow' => $params['bindflow'],
        ]);
        if (!$result) {
            return ['status' => false, 'message' => '更新失败', 'errorFields' => $validate->getErrors()];
        }
        if (!in_array($params['chargeway'], $this->chargeWay)) {
            return [
                'status' => false,
                'message' => '存在非法交付方式'
            ];
        }

        $sql = 'select projectid from ChargeWay where id = ? and status = ?';
        $var = [$chargeId, '01'];
        $result = Db::selectOne($sql, $var);
        if (empty($result)) {
            return [
                'status' => false,
                'message' => '交付方式不存在'
            ];
        }
        $projectId = $result['projectid'];

        //操作人权限校验，只有项目负责人能够修改
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }
//        //检查交付方式是否已被使用，已被使用不能修改
//        $sql = 'select id from CaseChargeWay where chargewayid = ? and status = ?';
//        $var = [$chargeId, '01'];
//        $result = Db::select($sql, $var);
//        if (!empty($result)) {
//            return [
//                'status' => false,
//                'message' => '该支付方式已被使用，无法编辑'
//            ];
//        }

        $oprInfo = UserAuth::getLoginInfo();
        $updateSql = 'update ChargeWay set chargeway=?,targetnum=?,bindflow=?,updater=?,updatername=?,updatedate=Now() where id = ? and status = ?';
        $updateVar = [
            $params['chargeway'],
            $params['targetnum'],
            $params['bindflow'],
            $oprInfo['userid'],
            $oprInfo['cname'],
            $chargeId,
            '01'
        ];
        $result = Db::update($updateSql, $updateVar);
        if (!$result) {
            Log::error('项目修改交付方式错误,projectid:' . $projectId);
            return [
                'status' => false,
                'message' => '更新失败'
            ];
        }

        return [
            'status' => true,
            'message' => '更新成功'
        ];
    }

    /**
     * 修改项目交付方式的收费标准
     * @param $chargeId
     * @param $standard
     * @return array
     */
    public function editChargeStandard($chargeId, $standard) {
        if (empty($chargeId)) {
            return [
                'status' => false,
                'message' => '交付方式id不能为空'
            ];
        }
        if (empty($standard)) {
            return [
                'status' => false,
                'message' => '收费标准不能为空'
            ];
        }
        $rule = [
            'standard|收费标准' => [
                'required', 'number', 'maxLength' => 100
            ],
            'salarytype|薪资类型' => [
                'required',
            ],
            'salaryfrom|薪资起始值' => [
                'number', 'min' => 0, 'max' => 200000000
            ],
            'salaryto|薪资结束值' => [
                'number', 'min' => 0, 'max' => 200000000
            ],
        ];

        $validate = new Validator($rule);
        $result = $validate->validate([
            'standard' => $standard['standard'],
            'salarytype' => $standard['salarytype'],
            'salaryfrom' => $standard['salaryfrom'],
            'salaryto' => $standard['salaryto']
        ]);
        if (!$result) {
            return ['status' => false, 'message' => '添加失败', 'errorFields' => $validate->getErrors()];
        }
        $sql = 'select projectid from ChargeStandard where id = ? and status = ?';
        $var = [$chargeId, '01'];
        $result = Db::selectOne($sql, $var);
        if (empty($result)) {
            return [
                'status' => false,
                'message' => '收费标准不存在'
            ];
        }
        $projectId = $result['projectid'];
        $check = $this->chkEditRight($projectId);
        if (!$check) {
            return [
                'status' => false,
                'message' => '您不是项目负责人，无修改权限'
            ];
        }
//        $sql = 'select id from CaseChargeWay where chargestandardid = ? and status = ?';
//        $var = [$chargeId, '01'];
//        $result = Db::select($sql, $var);
//        if (!empty($result)) {
//            return [
//                'status' => false,
//                'message' => '该收费方式已被使用，无法修改'
//            ];
//        }
        $oprInfo = UserAuth::getLoginInfo();
        $updateSql = 'update ChargeStandard set standard = ?,salarytype=?,salaryfrom=?,salaryto=?,updater=?,updatername=?,updatedate=Now() where id = ? and status = ?';
        $updateVar = [$standard['standard'], $standard['salarytype'], $standard['salaryfrom'], $standard['salaryto'], $oprInfo['userid'], $oprInfo['cname'], $chargeId, '01'];
        $result = Db::update($updateSql, $updateVar);
        return [
            'status' => $result ? true : false,
            'message' => $result ? '更新成功' : '更新失败'
        ];
    }

    /**
     * Notes:添加项目执行人
     * @param $projectId
     * @param $oprId
     * @return array
     */
    public function addOperator($projectId, $oprId) {
        if (!$this->chkEditRight($projectId)) {
            return ['status' => false, 'message' => '无修改权限'];
        }
        $user = UserAuth::getLoginInfo();
        $sql = 'select subid from ' . $this->tableName . ' where projectid = ?';
        $subId = Db::selectOne($sql, [$projectId]);
        if (!$subId) {
            return ['status' => false, 'message' => '添加失败'];
        }
        //项目执行人
        $sql = 'INSERT INTO ProjectOperator (subid,projectid,oprid,status,ischarger,creator,updator,createdate,updatedate)  VALUES ';
        $var = $values = [];
        foreach ($oprId as $item) {
            $values[] = '(?,?,?,?,?,?,?,Now(),Now())';
            $var1 = [$subId['subid'], $projectId, $item, '01', '0', $user['userid'], $user['userid']];
            $var = array_merge($var, $var1);
        }
        $sql .= implode(',', $values);
        $result = Db::connect('jyrpo_pdo')->insert($sql, $var);
        return $result ? ['status' => true, 'message' => '添加成功'] : ['status' => false, 'message' => '添加失败'];
    }


    /**
     * Notes:删除项目执行人
     * @param $projectId
     * @param $oprId
     * @return array
     */
    public function delOperator($projectId, $oprId) {
        if (!$this->chkEditRight($projectId)) {
            return ['status' => false, 'message' => '无修改权限'];
        }
        $user = UserAuth::getLoginInfo();
        $sql = 'select subid from ' . $this->tableName . ' where projectid = ?';
        $subId = Db::selectOne($sql, [$projectId]);
        if (!$subId) {
            return ['status' => false, 'message' => '修改失败'];
        }

        $sql = 'update ProjectOperator set status = ?, updator = ?, updatedate = NOW() where oprid = ? and projectid = ? and status = ?';
        $result = Db::update($sql, ['06', $user['userid'], $oprId, $projectId, '01']);
        return $result ? ['status' => true, 'message' => '修改失败'] : ['status' => false, 'message' => '修改失败'];
    }

    /**
     * Notes:转让项目负责人
     * @param $oprId
     * @param $projectId
     * @return bool|mixed
     */
    public function transferCharger($oprId, $projectId) {
        $sql = 'select subid from ' . $this->tableName . ' where projectid = ?';
        $subId = Db::selectOne($sql, [$projectId]);
        if (!$subId) {
            return false;
        }
        $subId = $subId['subid'];

        $sql = 'select 1 from ProjectOperator where projectid = ? and oprid = ? and status = ?';
        $operator = Db::selectOne($sql, [$projectId, $oprId, '01']);
        if (!$operator) {
            return false;
        }
        $userId = UserAuth::getLoginId();
        return Db::connect('jyrpo_pdo')->transaction(function () use ($oprId, $userId, $projectId, $subId) {
            //原有负责人
            $sql = 'update ProjectOperator set ischarger = ? ,updator = ?, updatedate = NOW() where projectid = ? and ischarger = ? and status = ?';
            $var = ['0', $userId, $projectId, '1', '01'];
            Db::connect('jyrpo_pdo')->update($sql, $var);
            //新负责人
            $sql = 'update ProjectOperator set ischarger = ? ,updator = ?, updatedate = NOW() where projectid = ? and oprid = ? and status = ?';
            $var = ['1', $userId, $projectId, $oprId, '01'];
            Db::connect('jyrpo_pdo')->update($sql, $var);

            // 添加职位职位执行人
            $sql = 'select distinct caseid from CaseOperator where projectid = ? and status = ?';
            $allCaseIds = array_column(Db::select($sql, [$projectId, '01']), 'caseid');
            if (!$allCaseIds) {
                return true;
            }
            //将此用户之前职位执行人先删除再统一添加
            $inFlag = substr(str_repeat('?,', count($allCaseIds)), 0, -1);
            $sql = 'update CaseOperator set status = ? ,updatedate = NOW() where oprid = ? and status = ? and caseid in (' . $inFlag . ')';
            Db::connect('jyrpo_pdo')->update($sql, array_merge(['06', $oprId, '01'], $allCaseIds));

            $sql = 'insert into CaseOperator (subid,projectid,caseid,oprid,status,createdate,updatedate) values';
            $var = $values = [];
            foreach ($allCaseIds as $caseId) {
                $values[] = '(?,?,?,?,?,NOW(),NOW())';
                $var1 = [
                    $subId,
                    $projectId,
                    $caseId,
                    $oprId,
                    '01',
                ];
                $var = array_merge($var, $var1);
            }
            $sql .= implode(',', $values);
            return Db::connect('jyrpo_pdo')->insert($sql, $var);
        });
    }

    /**
     * Notes:展示项目执行人
     * @param $projectId
     * @return array
     */
    public function showOperator($projectId) {
        $result = $this->chkGetRight($projectId);
        if (!$result) {
            return [];
        }
        $sql = 'select userid,cname,islock,ischarger,teamname from ProjectOperator as p left join User as u on p.oprid = u.userid left join Team as t on u.teamid = t.teamid where projectid = ? and p.status = ? ';
        return Db::select($sql, [$projectId, '01']);
    }

    /** 检查该公司下项目名称是否已存在
     * @param $subId
     * @param $projectName
     */
    public function chkprojectName($subId, $projectName) {
        $sql = 'SELECT projectid FROM Project WHERE subid=? AND projectname=?';
        $var = [$subId, $projectName];
        return Db::selectOne($sql, $var);
    }


    /**
     * Notes:当前用户可见项目
     * @param $params
     * @param $field
     * @param int $rowFrom
     * @param int $rowTo
     * @return array
     */
    public function myProject($params, $field, $rowFrom = 0, $rowTo = 0) {
        $user = UserAuth::getLoginInfo();
        $field = $field ?: 'p.projectid,p.subid,p.crmprojectnum,p.projectname,p.status,cs.subname,max(po.ischarger) as ischarger';

        $sql = 'select ' . $field . ' from Project as p LEFT join CustomerSub as cs on p.subid = cs.subid left join ProjectOperator as po on po.projectid = p.projectid left join User as u on po.oprid = u.userid where po.status = ? ';
        if ($field == 'count(1) as count') {
            $sql = 'select count(DISTINCT p.projectid) as count from Project as p LEFT join CustomerSub as cs on p.subid = cs.subid left join ProjectOperator as po on po.projectid = p.projectid left join User as u on po.oprid = u.userid where po.status = ? ';
        }
        $var = ['01'];
        //用户权限
        if ($user['issuper'] == 1) {

        } else if ($user['teamrole'] == 2) {
            $sql .= ' and u.teamcode like ? ';
            $var [] = $user['teamcode'] . '%';
        } else {
            $sql .= ' and u.userid = ? ';

            $var [] = $user['userid'];
        }
        //筛选参数
        if (isset($params['projectname']) && $params['projectname']) {
            $sql .= 'and projectname like ? ';
            $var[] = '%' . $params['projectname'] . '%';
        }
        if (isset($params['subid']) && $params['subid']) {
            $sql .= 'and p.subid = ? ';
            $var[] = $params['subid'];
        }
        if (isset($params['subname']) && $params['subname']) {
            $sql .= 'and subname like ? ';
            $var[] = '%' . $params['subname'] . '%';
        }

        if ($field == 'count(1) as count') {
            return Db::selectOne($sql, $var)['count'];
        }
        $sql .= ' group by p.projectid order by p.projectid desc';
        return Db::select($sql, $var, $rowFrom, $rowTo);
    }

    /**
     * 验证是否具备项目编辑权限
     * @param $projectId
     * @return bool
     */
    public function chkEditRight($projectId) {
        $loginInfo = UserAuth::getLoginInfo();
        if ($loginInfo['issuper'] == 1) {
            return true;
        }
        if ($loginInfo['teamrole'] == 1) {
            return $this->chkEditRightWithOprId($projectId, $loginInfo['userid']);
        } else {
            return $this->chkEditRightWithTeamCode($projectId, $loginInfo['teamcode']);
        }
    }

    /**
     * 验证是否具有项目查看权限
     * @param $projectId
     * @return bool
     */
    public function chkGetRight($projectId) {
        $loginInfo = UserAuth::getLoginInfo();
        if ($loginInfo['issuper'] == 1) {
            return true;
        }
        if ($loginInfo['teamrole'] == 1) {
            return $this->chkGetRightWithOprId($projectId, $loginInfo['userid']);
        } else {
            return $this->chkGetRightWithTeamCode($projectId, $loginInfo['teamcode']);
        }
    }

    /**
     * 根据用户id判断是否有项目查看权限
     * @param $projectId
     * @param $oprId
     * @return bool
     */
    public function chkGetRightWithOprId($projectId, $oprId) {
        $sql = 'select id from ProjectOperator where oprid=? and projectid=? and status=?';
        $var = [$oprId, $projectId, '01'];
        $result = Db::selectOne($sql, $var);
        return empty($result) ? false : true;
    }

    /**
     * 根据用户id判断是否有项目编辑权限
     * @param $projectId
     * @param $oprId
     * @return bool
     */
    public function chkEditRightWithOprId($projectId, $oprId) {
        $sql = 'SELECT ischarger FROM ProjectOperator WHERE status=? AND oprid=? AND projectid=?';
        $var = ['01', $oprId, $projectId];
        $result = Db::connect()->selectOne($sql, $var);
        return isset($result['ischarger']) && $result['ischarger'] == 1 ? true : false;
    }

    /**
     * 通过用户id获取交易公司下有编辑权限的项目id
     * @param $subId
     * @param $oprId
     * @return array
     */
    public function getHasEditRightProjectsWithOprId($subId, $oprId) {
        $sql = 'SELECT projectid FROM ProjectOperator WHERE status=? AND oprid=? AND subid=? AND ischarger=?';
        $var = ['01', $oprId, $subId, 1];
        $result = Db::select($sql, $var);
        return $result;
    }

    /**
     * 据用户团队编码判断是否有项目查看权限
     * @param $projectId
     * @param $oprTeamCode
     * @return bool
     */
    public function chkGetRightWithTeamCode($projectId, $oprTeamCode) {
        $sql = 'select id from ProjectOperator po LEFT JOIN User u on po.oprid=u.userid WHERE po.status=? AND u.status=? AND u.teamcode LIKE ? AND po.projectid=?';
        $var = ['01', '01', $oprTeamCode . '%', $projectId];
        $result = Db::connect()->selectOne($sql, $var);
        return empty($result) ? false : true;
    }

    /**
     * 根据用户团队编码判断是否有项目编辑权限
     * @param $projectId
     * @param $oprTeamCode
     * @return bool
     */
    public function chkEditRightWithTeamCode($projectId, $oprTeamCode) {
        $sql = 'select max(ischarger) as ischarger from ProjectOperator po LEFT JOIN User u on po.oprid=u.userid WHERE po.status=? AND u.status=? AND u.teamcode LIKE ? AND po.projectid=?';
        $var = ['01', '01', $oprTeamCode . '%', $projectId];
        $result = Db::connect()->selectOne($sql, $var);
        return isset($result['ischarger']) && $result['ischarger'] == 1 ? true : false;
    }

    /**
     * 通过teamcode获取交易公司下有编辑权限的项目id
     * @param $subId
     * @param $oprTeamCode
     * @return array
     */
    public function getHasEditRightProjectsWithTeamCode($subId, $oprTeamCode) {
        $sql = 'select po.projectid from ProjectOperator po LEFT JOIN User u on po.oprid=u.userid WHERE po.status=? AND u.status=? AND u.teamcode LIKE ? AND ischarger = ? AND subid = ?';
        $var = ['01', '01', $oprTeamCode . '%', 1, $subId];
        $result = Db::select($sql, $var);
        return $result;
    }

    //用户对接的项目
    public function oprProjectList($userid, $field = 'projectid') {
        $sql = 'select ' . $field . ' from ProjectOperator left join User on oprid=userid where (oprid = ? or teamcode like ?) and ProjectOperator.status = ?';
        return Db::select($sql, [$userid, UserAuth::getLoginInfo('teamcode', '') . '%', '01']);
    }

    /**
     * Notes:用项目id批量查项目对接人
     * @param array $projectIds
     * @return array
     */
    public function operatorList(array $projectIds) {
        if (!$projectIds) {
            return [];
        }
        $inFlag = substr(str_repeat('?,', count($projectIds)), 0, -1);
        $sql = 'SELECT userid,cname,projectid,ischarger FROM User as u
                LEFT JOIN ProjectOperator as po ON u.userid = po.oprid
                where po.status = ? and po.projectid  in(' . $inFlag . ') order by projectid desc,ischarger desc';
        $var = array_merge(['01'], $projectIds);
        $result = Db::select($sql, $var);
        if (empty($result)) {
            return [];
        }
        $userList = [];
        foreach ($result as $value) {
            $userList[$value['projectid']][] = $value;
        }
        return $userList;
    }

    public function chkProjectId(array $projectIds) {
        if (!$projectIds) {
            return [];
        }
        $inFlag = substr(str_repeat('?,', count($projectIds)), 0, -1);
        $sql = 'select subid,projectid from Project where projectid in (' . $inFlag . ') and status = ?';
        $result = Db::select($sql, array_merge($projectIds, ['01']));
        $subList = [];
        foreach ($result as $value) {
            $subList[$value['projectid']] = $value['subid'];
        }
        return $subList;
    }

    public function getProjectListById(array $projectIds, $field = null) {
        if (!$projectIds) {
            return [];
        }
        $projectIds = array_unique($projectIds);
        $inFlag = substr(str_repeat('?,', count($projectIds)), 0, -1);
        $field = $field ?? 'subid,projectid,projectname';
        $sql = 'select ' . $field . ' from Project where projectid in (' . $inFlag . ')';
        $result = Db::select($sql, $projectIds);
        $subList = [];
        foreach ($result as $value) {
            $subList[$value['projectid']] = $value;
        }
        return $subList;
    }

    /**
     * 获取项目信息
     * @param $projectId
     * @param null $field
     * @return mixed
     */
    public function getProjectInfo($projectId, $field = null) {
        $field = $field ?? 'subid,projectid,projectname';
        $sql = 'select ' . $field . ' from Project where projectid = ?';
        return Db::selectOne($sql, [$projectId]);
    }

    /**
     * Notes:获取项目执行人
     * @param $subId
     * @param $projectId
     * @param string $isCharger
     * @return array
     */
    public function getProjectOpr($subId, $projectId, $isCharger = '') {
        $sql = 'select id,subid,projectid,oprid,status,ischarger from ProjectOperator where subid = ? and projectid = ?';
        $params = [$subId, $projectId];
        if ($isCharger != '' && in_array($isCharger, [0, 1])) {
            $sql .= " and ischarger=? ";
            $params[] = $isCharger;
        }

        return Db::select($sql, $params);
    }

    public function getContactFieldList($projectId) {
        $result = $this->chkGetRight($projectId);
        $myCase = (new CaseOperator())->myAllCase(UserAuth::getLoginId());
        $myCaseProjectIds = array_column($myCase, 'projectid');
        if (!$result && !in_array($projectId, $myCaseProjectIds)) {
            return [
                'status' => false,
                'message' => '项目不存在或无权查看',
                'contactfieldlist' => []
            ];
        }
        if (empty($projectId)) {
            return [
                'status' => false,
                'message' => '项目id不能为空',
                'contactfieldlist' => []
            ];
        }
//        $sql = 'select oprid from CaseOperator where projectid=? and status=?';
//        $var = [$projectId,'01'];
//        $result = Db::select($sql,$var);
//        $oprs1 = array_column($result,'oprid');
//
//        $sql = 'select oprid from ProjectOperator where projectid=? and status=?';
//        $var = [$projectId,'01'];
//        $result = Db::select($sql,$var);
//        $oprs2 = array_column($result,'oprid');
//
//        $oprs = array_merge($oprs1,$oprs2);var_dump($oprs);
//
//        if (!in_array(UserAuth::getLoginId(),$oprs)) {
//            return [
//                'status' => false,
//                'message' => '您无权查看该信息',
//                'fieldlist' => []
//            ];
//        }
        $sql = 'select id,fieldname,showname,unit,type,arguments,issys from ContactField where projectid = ? and status = ?';
        $var = [$projectId, '01'];
        $resultList = Db::select($sql, $var);
        foreach ($resultList as &$item) {
            $item['arguments'] = json_decode($item['arguments'], true);
        }
        unset($item);
        return [
            'status' => true,
            'message' => '获取成功',
            'contactfieldlist' => $resultList
        ];
    }

    public function getChargeWayList($projectId) {
        $result = $this->chkGetRight($projectId);
        $myCase = (new CaseOperator())->myAllCase(UserAuth::getLoginId());
        $myCaseProjectIds = array_column($myCase, 'projectid');
        if (!$result && !in_array($projectId, $myCaseProjectIds)) {
            return [
                'status' => false,
                'message' => '项目不存在或无权查看',
                'fieldlist' => []
            ];
        }
        if (empty($projectId)) {
            return [
                'status' => false,
                'message' => '项目id不能为空',
                'fieldlist' => []
            ];
        }
//        $sql = 'select oprid from CaseOperator where projectid=? and status=?';
//        $var = [$projectId,'01'];
//        $result = Db::select($sql,$var);
//        $oprs1 = array_column($result,'oprid');
//
//        $sql = 'select oprid from ProjectOperator where projectid=? and status=?';
//        $var = [$projectId,'01'];
//        $result = Db::select($sql,$var);
//        $oprs2 =  array_column($result,'oprid');
//
//        $oprs = array_merge($oprs1,$oprs2);
//
//        if (!in_array(UserAuth::getLoginId(),$oprs)) {
//            return [
//                'status' => false,
//                'message' => '您无权查看该信息',
//                'fieldlist' => []
//            ];
//        }
        $sql = 'select cs.id,chargeway,targetnum,bindflow,chargeid,chargetype,standard,salarytype,salaryfrom,salaryto
                from ChargeStandard as cs left join ChargeWay as cw on cs.chargeid=cw.id
                where cs.projectid = ? and cs.status = ?';
        $var = [$projectId, '01'];
        $resultList = Db::select($sql, $var);
        $tmpList = [];
        foreach ($resultList as &$item) {
            $tmpList[$item['chargeid']][] = [
                'id' => $item['id'],
                'chargetype' => $item['chargetype'],
                'standard' => $item['standard'],
                'salarytype' => $item['salarytype'],
                'salaryfrom' => $item['salaryfrom'] == 0 ? '' : $item['salaryfrom'],
                'salaryto' => $item['salaryto'] == 0 ? '' : $item['salaryto']
            ];
        }
        foreach ($resultList as &$item) {
            $item['bindflow'] = explode(',', $item['bindflow']);
            foreach ($item['bindflow'] as &$flow) {
                $flow = [substr($flow, 0, 2), substr($flow, 2, 2)];
            }
            unset($flow);
            $item['children'] = $tmpList[$item['chargeid']];
            unset($item['chargetype']);
            unset($item['standard']);
            unset($item['salarytype']);
            unset($item['salaryfrom']);
            unset($item['salaryto']);
            unset($item['id']);
        }
        unset($item);
        $resultList = array_values(array_unique($resultList, SORT_DESC));
        return [
            'status' => true,
            'message' => '获取成功',
            'chargewaylist' => $resultList
        ];
    }

    public function checkCrmExist($crmNum) {
        $sql = 'select projectid from ' . $this->tableName . ' where crmprojectnum = ? and status = ?';
        $crm = Db::selectOne($sql, [$crmNum, '01']);
        if ($crm) {
            $sql = 'select cname,teamcode from ProjectOperator as po left join User as u on po.oprid = u.userid where po.projectid = ? and ischarger = ?';
            $charger = Db::selectOne($sql, [$crm['projectid'], 1]);
            $fullTeamName = (new Team())->fullName($charger['teamcode']);
            return [
                'status' => false,
                'message' => 'CRM项目编号：[' . $crmNum . '] 已被项目id：' . $crm['projectid'] . ' 使用，项目负责人：' . $fullTeamName . ' ' . $charger['cname']
            ];
        }
        return [
            'status' => true,
            'message' => 'CRM项目编号：[' . $crmNum . '] 未被使用'
        ];
    }

    /**
     * 获取交易公司下有编辑权限的项目id
     * @param $subId
     * @return array
     */
    public function getHasEditRightProjects($subId) {
        $loginInfo = UserAuth::getLoginInfo();
        if ($loginInfo['issuper'] == 1) {
            $sql = 'select projectid from SCase where status = ?';
            $var = ['01'];
            return Db::select($sql, $var);
        }
        if ($loginInfo['teamrole'] == 1) {
            return $this->getHasEditRightProjectsWithOprId($subId, $loginInfo['userid']);
        } else {
            return $this->getHasEditRightProjectsWithTeamCode($subId, $loginInfo['teamcode']);
        }
    }
}